<?php
/**
 * HackInPain_Engine_Abstract est la classe centrale du moteur.
 * @author François Guégnaud
 * @property _gate_defaults_rules
 * @method init()
 * @method run()
 */
Abstract class HackInPain_Engine_Abstract extends HackInPain_Singleton_Abstract {
	
	/**
	 * Gate rules by default
	 * @var array
	 */
	static protected $_gate_defaults_rules = null;
	
	protected $_constant_routes = null;
	
	protected $_view = null;
	
	// array contains controllers returns
	protected $_return = null;

	/**
	 * Run the engine
	 */
	public function run() {
		
		$gate = HackInPain_Engine_Gate::getInstance();
		$gate->rewriteURL(self::$_gate_defaults_rules);

		// Router
		$router = HackInPain_Engine_Router::getInstance();
		// Récupère les controllers et actions à exécuter
		foreach ($router->getRoutes() as $route) {

			$controllerName = $route->getController();
			$controller = new $controllerName();

			$actionName = $route->getAction();
			$this->_return[$controllerName] = $controller->$actionName();
			
			$this->_view[$controllerName] = new HackInPain_View();
			$this->_view[$controllerName]->content = $controller->view;
			$this->_view[$controllerName]->setFile($route->getShortController());
			$this->_view[$controllerName]->action = $actionName;
			
			// Ajout du CSS
			$css_file='css/'.$route->getShortController().'.css';
			if(file_exists($css_file)) {
				$this->_view[$controllerName]->css =
					'<link id="css-'.$route->getShortController().'" rel="stylesheet" type="text/css" href="/'.$css_file.'"/>';
			} //else echo "le fichier $css_file n'existe pas<br />";
			
			// Ajout du JavaScript
			$js_file='js/'.$route->getShortController().'.js';
			if(file_exists($js_file)) {
				//$this->_view[$controllerName]->js = $js_file;
				$this->_view[$controllerName]->js =
					'<script id="js-'.$route->getShortController().'" src="/'.$js_file.'" class="addedJS"></script>';
			} //else echo "le fichier $js_file n'existe pas<br />";
		}
	
		// Gestion des vues en fonction du format attendu
		switch($gate->getFormat()) {
			default:
				require_once 'Application/Layout.phtml';
			break;
			// TODO: trancher entre ajax et autre
			// Pour les requêtes AJAX, on n'envoi pas le layout mais uniquement la vue
			// ajax n'est pas un bon terme, car designe un ensemble de technologie,
			// pas le resultat attendu. une requete ajax peut attendre en retour du json!
			case 'ajax': 
			case 'partial':
				foreach($this->_view as $view) {
					require_once $view->getFile();
				}
			break;
			case 'json': // Pour les requêtes JSON, on n'envoi rien
				foreach($this->_return as $return) {
					if(!is_null($return)) {
						echo json_encode($return);
					}
					
				}
			break;
		}

	}
		
	/**
	 * Set defaults gate rules
	 */
	static public function setGateDefaultsRules (array $rules) {
		self::$_gate_defaults_rules = $rules;
	}
	
	/**
	 * Set $_constant_routes
	 * @param array $routes
	 */
	public function setConstantRoutes(array $routes) {
		$this->_constant_routes = $routes;
	}
	
	/**
	 * Get $_constant_routes
	 * @return array $_constant_routes
	 */
	public function getConstantRoutes() {
		return $this->_constant_routes;
	}
} 